import React from 'react';
import { Select, Button, Card, Tabs, Input, Row } from 'antd';
//import { PageContainer } from '@ant-design/pro-layout';
import { UnControlled as CodeMirror } from 'react-codemirror2';
import { uploadCode } from '@/services/online_compiler';
import styles from './style.less';
import 'codemirror/lib/codemirror.js';
import 'codemirror/lib/codemirror.css';
// 主题风格
import 'codemirror/theme/solarized.css';
// 代码模式，clike是包含java,c++等模式的
import 'codemirror/mode/clike/clike';
import 'codemirror/mode/python/python';
import 'codemirror/mode/css/css';
//ctrl+空格代码提示补全
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/anyword-hint.js';
//代码高亮
import 'codemirror/addon/selection/active-line';
//折叠代码
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/edit/closebrackets';
import 'codemirror/addon/edit/matchBrackets';
import {PageContainer} from "@ant-design/pro-layout";

const { TextArea } = Input;
const { Option } = Select;
const { TabPane } = Tabs;

enum CompilerLanguage {
  CPP = 'text/x-c++src',
  JDK = 'text/x-java',
  PYTHON = 'text/x-cython',
}

export default class OnlineCompiler extends React.Component<any, any> {
  private input: string = '';
  private codeEditor: any;

  private codeRecord: { [k in CompilerLanguage]: string } = {
    [CompilerLanguage.CPP]: '',
    [CompilerLanguage.JDK]: '',
    [CompilerLanguage.PYTHON]: '',
  };

  constructor(props: any) {
    super(props);
    this.state = {
      currentCompiler: CompilerLanguage.CPP,
      activeKey: 'input',
      output: '',
    };
  }

  // 切换编译器类型
  private readonly onSelectChange = (value: CompilerLanguage) => {
    this.codeRecord[this.state.currentCompiler] = this.codeEditor.getValue();
    this.setState({ currentCompiler: value });
    this.codeEditor.setValue(this.codeRecord[value]);
  };

  // 提交代码
  private readonly onUploadCode = async () => {
    uploadCode(
      Object.assign({
        type: this.state.currentCompiler,
        input: this.input,
        code: this.codeEditor.getValue(),
      }),
    ).then((response: { code: number; data: any; msg: string }) => {
      this.setState({ activeKey: 'output', output: response.data });
    });
  };

  render() {
    return (
      <PageContainer>
        <div className={styles.box}>
          <div className={styles.box_jz}>
            <Card>
              <Select
                defaultValue={this.state.currentCompiler}
                style={{ width: 200 }}
                onChange={this.onSelectChange}
              >
                <Option value={CompilerLanguage.CPP}>C++</Option>
                <Option value={CompilerLanguage.JDK}>JDK 1.8</Option>
                <Option value={CompilerLanguage.PYTHON}>Python</Option>
              </Select>

              <CodeMirror
                editorDidMount={(editor) => {
                  editor.setSize('100%', '500');
                  editor.setValue(this.codeRecord[this.state.currentCompiler]);
                  this.codeEditor = editor;
                }}
                options={{
                  mode: { name: this.state.currentCompiler },
                  theme: 'solarized dark',
                  autofocus: true, //自动获取焦点
                  styleActiveLine: true, //光标代码高亮
                  lineNumbers: true, //显示行号
                  smartIndent: true, //自动缩进
                  //start-设置支持代码折叠
                  lineWrapping: true,
                  foldGutter: true,
                  gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'], //end
                  matchBrackets: true, //括号匹配，光标旁边的括号都高亮显示
                  autoCloseBrackets: true, //键入时将自动关闭()[]{}''""
                }}
              />
              <Tabs
                defaultActiveKey="input"
                activeKey={this.state.activeKey}
                onChange={(acKey) => this.setState({ activeKey: acKey })}
              >
                <TabPane tab="输入" key="input">
                  <TextArea
                    className={styles.inputArea}
                    onChange={(e) => {
                      this.input = e.target.value;
                    }}
                  />
                </TabPane>
                <TabPane tab="输出" key="output">
                  <div>{this.state.output}</div>
                </TabPane>
              </Tabs>
              <Row justify="end">
                <Button type="primary" size="large" onClick={this.onUploadCode}>
                  Submit
                </Button>
              </Row>
            </Card>
          </div>
        </div>
      </PageContainer>
    );
  }
}
